#ifndef _CONFFILE_H_
#define _CONFFILE_H_

#include <map>
#include <string>
#include <vector>

class yyFlexLexer;
using namespace std;


enum atom_types {
        T_INT,
        T_FLOAT,
        T_LIST,
        T_BOOLEAN,
        T_STRING,
        T_NULL };

union DataNode
{
      struct 
      {
              int type;
      } t;

      struct t_int
      {
              int type;
              int val;
      } t_int;

      struct 
      {
              int type;
              float val;
      } t_float;

      struct 
      {
              int type;
              bool val;
      } t_bool;

      struct 
      {
              int type;
              int size;
              char * val;
      } t_string;

      struct 
      {
              int type;
              int size;
              DataNode * val;
      } t_list;
};

typedef map<string,DataNode> Node;

//! Parsea y permite usar archivos de configuracion muy simples
class ConfFile : public yyFlexLexer
{
public:
    //! Constructor por defecto
    ConfFile();
    //! Constructor a partir de un nombre de fichero
    ConfFile(string fname);
    //! Destructor
    ~ConfFile();
    
    //! Destruye el diccionario y carga un archivo nuevo
    void load(string fname);

    //! Vuelca el contenido del diccionario a un archivo
    void write(string fname);

    //! Pregunta si existe determinada clave
    bool exists(string node,string key);
    
    //! Parsea el fichero de entrada, heredado de FlexLexer
    int yylex();

    //! Devuelve los datos de la clave asociada
    DataNode getDataNode(string node, string key);

    //! Establece los datos de la clave asociada
    void setDataNode(string node, string key, DataNode data);

    //! Devuelve un valor entero
    int getInt(string node, string key);
    
    //! Devuelve un valor flotante
    float getFloat(string node, string key);

    //! Devuelve una lista de enteros
    vector<int> getIntList(string, string);

    //! Devuelve una lista de floats
    vector<float> getFloatList(string, string);

    //! Devuelve una cadena
    string getString(string,string);

    //! Devuelve un booleano
    bool getBool(string, string);

    //! Devuelve los nodos del archivo de configuracion
    vector<string> getNodes();
    
    //! Devuelve los nombres del nodo asociado
    vector<string> getKeys(string node);

    

private:
  
    map<string,Node> nodes;

    //Datos que necesita el lexer a nivel de clase
    string current_token;
    string current_value;
    string current_node;
    vector<DataNode> current_list;
    DataNode current_data;
};

#endif

/* ex: set cindent expandtab softtabstop=4 shiftwidth=4 tabstop=4: */
